#coding: utf-8
import os, logging, requests
# from cStringIO import StringIO
try:
    from io import StringIO
except ImportError:
    from cStringIO import StringIO
from io import BytesIO
from PIL import Image, ImageFont, ImageDraw
from django.utils import lru_cache
from disn.utilities import *
from account.models import *



logger = logging.getLogger(__name__)
Header_Font = ImageFont.truetype(os.path.join(os.path.dirname(__file__), 'static/share_post/STHEITI.ttf'), 60)
Body_Font = ImageFont.truetype(os.path.join(os.path.dirname(__file__), 'static/share_post/STHEITI.ttf'), 40)
TPL_ITEM_POST_IMAGE_PATH = os.path.join(os.path.dirname(__file__), 'static/share_post/simple.jpg')
TPL_USER_POST_IMAGE_PATH = os.path.join(os.path.dirname(__file__), 'static/share_post/simple.jpg')
# LOGO_PATH = os.path.join(os.path.dirname(__file__), 'static/share_post/favicon.jpeg')
# UGULU_LOGO_PATH = os.path.join(os.path.dirname(__file__), 'static/share_post/ugulu_logo.jpg')
LINE_SPACING = 20


def get_circular_mask(avatar):
    bigsize = (avatar.size[0] * 3, avatar.size[1] * 3)
    mask = Image.new('L', bigsize, 0)
    draw = ImageDraw.Draw(mask)
    draw.ellipse((0, 0) + bigsize, fill=255)
    # avatar.putalpha(mask)
    return mask.resize(avatar.size, Image.ANTIALIAS)


def draw_header(tpl, avatar, uname):
    avatar = avatar.resize((120, 120), Image.ANTIALIAS)
    header_txt = u' %s分享推荐' % uname
    im_width, im_height = tpl.size
    avatar_width, avatar_height = avatar.size
    txt_width, txt_height = Header_Font.getsize(header_txt)
    region_width = txt_width + avatar_width
    region_height = txt_height + avatar_height

    header_x = (im_width - region_width) // 2
    header_y = (360 - region_height) // 2

    tpl.paste(avatar, box=(header_x, header_y), mask=get_circular_mask(avatar))
    dr = ImageDraw.Draw(tpl)
    dr.text((header_x + avatar_width, header_y+(avatar_height-txt_height)/2.5), header_txt,
            font=Header_Font, fill='white')
    return tpl



# def draw_body(tpl, title, image_url, desc, mall, price, qr)
def draw_body(tpl, item, qr):
    title = '[%s]%s' %(item.article_mall, item.article_title.strip())
    desc = '%s\n%s' %(item.article_price, item.article_summary)
    im_width, im_height = tpl.size
    dr = ImageDraw.Draw(tpl)
    title_font_width, title_font_height = dr.textsize(title, Header_Font, spacing=LINE_SPACING)
    title_buf = []
    title_line_width = 0
    title_line_max_height = Header_Font.getsize(title[0])[1] if len(title) > 0 else 0
    title_height = 0
    container_width = im_width * 0.93
    # title is limited in a container
    if title_font_width >= container_width:
        for chr in title:
            chr_width, chr_height = Header_Font.getsize(chr)
            title_line_max_height = max(title_line_max_height, chr_height)
            if title_line_width + chr_width >= container_width or chr == '\n':
                title_height += title_line_max_height + LINE_SPACING - 4.5  # some gap?
                if title_height > im_height * 0.4:
                    title_buf[-1] = '...'
                    title_height -= LINE_SPACING
                    break
                if title_line_width + chr_width >= container_width:
                    # If line exceeds container width, insert a carriage return
                    title_buf.append('\n')
                elif chr == '\n':
                    chr_width = 0
                title_line_width = 0
                title_line_max_height = 0
            title_buf.append(chr)
            title_line_width += chr_width
        else:
            title_height += title_line_max_height
        title = ''.join(title_buf)
        title_font_width, title_font_height = dr.textsize(title, Header_Font, spacing=LINE_SPACING)
    else:
        title_line_width = title_font_width
        title_height = title_font_height

    title_x = (im_width - title_font_width) // 2
    # title_y = (im_height - title_height) // 5
    title_y = 50
    # Draw title
    title_offset = (title_x, title_y)
    dr.text(title_offset, title, font=Header_Font, fill='#545255', spacing=LINE_SPACING)
    # Draw quotes
    # quote_font = Header_Font
    # quote_offset = quote_font.getsize(u'“')
    # dr.text((title_offset[0] - quote_offset[0], title_offset[1]),
    #         u'“', font=quote_font, fill='#3784f8')
    # dr.text((title_offset[0] + title_line_width, title_offset[1] + title_height - title_line_max_height),
    #         u'”', font=quote_font, fill='#3784f8')

    # Draw qiniu
    image_url = item.qiniu_pic if item.qiniu_pic.startswith('http') else 'https:%s' %item.qiniu_pic
    # print('image_url=%s' %image_url)
    qiniu_pic = Image.open(BytesIO(http_get_bytes(image_url)))
    qiniu_pic = qiniu_pic.resize((400, 400), Image.ANTIALIAS)
    qiniu_pic_width, qiniu_pic_height = qiniu_pic.size
    # print(tpl.size, qiniu_pic.size)
    # box_x = (im_width - qiniu_pic_width) // 2
    box_x = 100
    # box_y = im_height - qiniu_pic_height
    box_y = int(title_y + title_height + 25)
    # print(box_x, box_y)
    tpl.paste(qiniu_pic, box=(box_x, box_y))

    draw_qrcode(tpl, qr, box_x + 400 + 40, box_y + 60)

    # Draw body
    container_width = im_width * 0.9
    body_font_width, body_font_height = dr.textsize(desc, Body_Font, spacing=LINE_SPACING)
    body_buf = []
    body_line_width = 0
    body_line_max_height = Body_Font.getsize(desc[0])[1] if len(desc) > 0 else 0
    body_height = 0
    # desc is limited in a container
    if body_font_width >= container_width:
        for chr in desc:
            chr_width, chr_height = Body_Font.getsize(chr)
            body_line_max_height = max(body_line_max_height, chr_height)
            if body_line_width + chr_width >= container_width or chr == '\n':
                body_height += body_line_max_height + LINE_SPACING - 4.5  # some gap?
                if body_height > im_height * 0.4:
                    body_buf[-1] = '...'
                    body_height -= LINE_SPACING
                    break
                if body_line_width + chr_width >= container_width:
                    # If line exceeds container width, insert a carriage return
                    body_buf.append('\n')
                elif chr == '\n':
                    chr_width = 0
                body_line_width = 0
                body_line_max_height = 0
            body_buf.append(chr)
            body_line_width += chr_width
        else:
            body_height += body_line_max_height
        desc = ''.join(body_buf)
        body_font_width, body_font_height = dr.textsize(desc, Body_Font, spacing=LINE_SPACING)
    else:
        body_line_width = body_font_width
        body_height = body_font_height

    body_x = (im_width - body_font_width) // 2
    # body_y = (im_height - body_height) // 5
    body_y = box_y + 420
    # Draw body
    body_offset = (body_x, body_y)
    dr.text(body_offset, desc, font=Body_Font, fill='#545255', spacing=LINE_SPACING)

    return tpl


def draw_qrcode(tpl, qr, box_x, box_y):
    qr = qr.resize((250, 250), Image.ANTIALIAS)
    qr_width, qr_height = qr.size
    qr = qr.convert('RGB')
    # im_width, im_height = tpl.size
    # box_x = im_width - qr_width - 30
    # box_y = im_height - qr_height - 30
    tpl.paste(qr, box=(box_x, box_y))
    return tpl


@lru_cache.lru_cache(maxsize=128)
def http_get_bytes(url):
    # idempotent, so it can be cached
    resp = requests.get(url)
    resp.raise_for_status()
    return resp.content


def draw_item_post(user_profile, qrcode_type, item):
    try:
        avatar = Image.open(BytesIO(http_get_bytes(user_profile.headimgurl)))
    except Exception as e:
        avatar = Image.new('RGB', (128, 128), 'white')
    share, share_created = UserShare.objects.get_or_create(goods_item_id=item.id, owner=user_profile.user, qrcode_type=qrcode_type, share_type='1', active=True)
    qr_url = None
    if share_created:
        result = None
        if qrcode_type == '1':
            result = get_permanent_qrcode(share.id)
            if result:
                share.qrcode_expire_at = None
        else:
            result = get_temporary_qrcode(share.id)
            if result:
                share.qrcode_expire_at = datetime.datetime.now() + datetime.timedelta(seconds=result['ticket']['expire_seconds'])
        if result:
            share.qrcode_ticket = result['ticket']['ticket']
            share.is_redirect = True
            share.save()
            if share.qrcode_ticket and share.qrcode_ticket != 'None':
                qr_url = result['qrcode'].url
            else:
                qr_url = None
    else:
        if share.qrcode_ticket and share.qrcode_ticket != 'None':
            qr_url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s' %share.qrcode_ticket
        else:
            qr_url = None
    if qr_url:
        qr = Image.open(BytesIO(http_get_bytes(qr_url)))
        tpl = Image.open(TPL_ITEM_POST_IMAGE_PATH)
        # draw_header(tpl, avatar, user_profile.nickname)
        draw_body(tpl, item, qr)
        logo_path = user_profile.headimgurl
        # draw_qrcode(tpl, qr, logo_path)
        tpl = tpl.resize((tpl.width//3, tpl.height//3), Image.ANTIALIAS)
        logger.info('%s requests a share post for %s', user_profile.nickname, item.article_title)
        return tpl
    else:
        share.delete()
        return None


def draw_user_post(user_profile, qrcode_type='0'):
    try:
        avatar = Image.open(BytesIO(http_get_bytes(user_profile.headimgurl)))
    except Exception as e:
        avatar = Image.new('RGB', (64, 64), 'white')
    share, share_created = UserShare.objects.get_or_create(goods_item=None, owner=user_profile.user, qrcode_type=qrcode_type, share_type='0', active=True)
    qr_url = None
    if share_created:
        result = None
        if qrcode_type == '1':
            result = get_permanent_qrcode(share.id)
            share.qrcode_expire_at = None
        else:
            result = get_temporary_qrcode(share.id)
            share.qrcode_expire_at = datetime.datetime.now() + datetime.timedelta(seconds=result['ticket']['expire_seconds'])
        qr_url = result['qrcode'].url
        share.qrcode_ticket = result['ticket']['ticket']
            # qr_url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s' %share.qrcode_ticket

        share.save()
    else:
        qr_url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s' %share.qrcode_ticket
    if qr_url:
        qr = Image.open(BytesIO(http_get_bytes(qr_url)))
        tpl = Image.open(TPL_USER_POST_IMAGE_PATH)
        logo_path = user_profile.headimgurl

        header_avatar = avatar.resize((60, 60), Image.ANTIALIAS)
        im_width, im_height = tpl.size
        avatar_width, avatar_height = header_avatar.size
        txt_width, txt_height = Header_Font.getsize(user_profile.nickname)
        region_width = txt_width + avatar_width
        region_height = txt_height + avatar_height

        header_x = (im_width - region_width) // 2 + 170
        header_y = (360 - region_height) // 2 + 65

        tpl.paste(header_avatar, box=(header_x, header_y), mask=get_circular_mask(header_avatar))
        # dr = ImageDraw.Draw(tpl)
        # dr.text((header_x + avatar_width, header_y+(avatar_height-txt_height)/2.5), user_profile.nickname,
        #         font=Header_Font, fill='orange')

        # draw_header(tpl, avatar, user_profile.nickname)
        # draw_body(tpl, text, image_url)

        # draw qrcode image
        qr = qr.resize((200, 200), Image.ANTIALIAS)
        qr_width, qr_height = qr.size
        qr = qr.convert('RGB')

        # Paste logo
        logo = header_avatar.resize((qr_width//5, qr_height//5), Image.ANTIALIAS)
        logo_width, logo_height = logo.size
        qr.paste(logo, box=((qr_width-logo_width)//2, (qr_height-logo_height)//2))

        # Paste QR code
        im_width, im_height = tpl.size
        box_x = im_width - qr_width - 70
        box_y = im_height - qr_height - 40
        tpl.paste(qr, box=(box_x, box_y))
        # tpl = tpl.resize((tpl.width//2, tpl.height//2), Image.ANTIALIAS)

        return tpl
    else:
        return None